<?php

namespace App\Clients\Keruyun;

use App\Clients\BaseClient;
use App\Models\Account;
use App\Services\JinShouFuHelper;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Database\Eloquent\Model;
use Psr\Http\Message\ResponseInterface;

abstract class KeruyunClient extends BaseClient
{
    protected Model $account;

    const MAX_TRYIES = 10;

    protected $isJson = true;

    protected $queryData = [];

    protected $isLogin = true;

    /**
     * @throws Exception
     * @throws GuzzleException
     */
    public function __construct(Model $account)
    {
        parent::__construct();
        if(!($account instanceof Account)){
            $this->account = $account->account;
        }else{
            $this->account = $account;
        }
//        if($this->isLogin){
//            $this->login();
//        }

        if($this->account->login_status != 1
            || empty($this->account->logout_at)
        ){
            if($this->isLogin){
                $this->login();
            }

        }
    }

    /**
     * @throws Exception
     * @throws GuzzleException
     */
    public function login(): void
    {
//        var_dump(123);
//        exit();
        $cookieJar = new CookieJar();
        $client = new Client([
            "verify"=>false,
            "http_errors"=>false,
            'cookies' => $cookieJar,
        ]);
        $wuConfig = $client->get("https://ynuf.aliapp.org/w/wu.json",[
            "headers"=>[
                "User-Agent"=>"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36",
            ]
        ]);
        $wuConfig = $wuConfig->getBody()->getContents();
        preg_match("/__fycb\('(.+)'\)/",$wuConfig,$match);
        $wuConfig = $match[1];
        $cmd = "node ".public_path("password.js");
        $password = trim(shell_exec($cmd));
        $postData = [
            "loginId"=>$this->account->name,
            "password"=>$password,
            "countryCode"=>"86",
            "agreementAccepted"=>true,
        ];
        $headers = [
            "User-Agent"=>"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36",
            "bx-umidtoken"=>$wuConfig
        ];
//        var_dump($headers);
//        var_dump($postData);
//        exit();
        $url = "https://epassport.keruyun.com/auth/web/login";
        $response = $client->post($url,[
            "headers"=>$headers,
            "json"=>$postData
        ]);
        $response = $response->getBody()->getContents();
        $content = json_decode($response,true);
//        var_dump($content);
//        exit();
        if($content["code"] != "SUCCESS") throw new Exception("登录失败...");
        $cookies = $cookieJar->toArray();
        $cookieStr = [];
        foreach ($cookies as $cookie){
            if($cookie["Name"] == "kbsaas_salt"){
                $cookie["Value"] = urldecode($cookie["Value"]);
            }
            $cookieStr[$cookie["Name"]] = $cookie["Value"];
        }
        $this->account->cookies = json_encode($cookieStr);
        $this->account->login_status = 1;
        $this->account->logout_at = date("Y-m-d H:i:s",time() + 86400);
        $this->account->save();
        $client = new SwitchOrganization($this->account);
        $response = $client->loopExecute(null)->contents();
//        var_dump($response);
//        exit();
    }

    abstract public function execute($queryData);

    public function headers($other = []): array
    {
        $cookie = json_decode($this->account->cookies,true);
        $bodyData = json_encode($this->queryData).$cookie["kbsaas_salt"];
        $bodyData = md5($bodyData);
        $headers = [
            "User-Agent"=>'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.6045.9 Safari/537.36',
            "Referer"=>"https://pos.keruyun.com",
            "x-gw-sid"=>$cookie["kbsaas_gw_x_sid"],
            "x-gw-sign"=>$bodyData,
        ];
//        var_dump($headers);
//        exit();
//
        return array_merge($headers,$other);
    }


    /**
     * @throws Exception
     */
    protected function isLogout(ResponseInterface $response){
        $content = $response->getBody()->getContents();
//        var_dump($content);
//        exit();
        $content = json_decode($content,true);
        if(empty($content["code"]) || $content["code"] != "SUCCESS_OK"){
            $this->account->login_status = 0;
            $this->account->save();
            throw new Exception("掉线了");
        }
        return $content;
    }

    protected function getQueryData($postData)
    {
        if(empty($postData) && empty($this->queryData)) return $postData;
        if(!empty($postData)){
            return $postData;
        }
        if(!empty($this->queryData)){
            return $this->queryData;
        }
        return $postData;
    }

    /**
     * @throws Exception
     * @throws GuzzleException
     */
    public function loopExecute($postData): static
    {
        $this->queryData = $this->getQueryData($postData);

        for($i=0;$i<=self::MAX_TRYIES;$i++){
            try{
                return $this->execute($this->queryData);
            }catch (Exception $e){
                var_dump($e->getMessage());
                if($e->getMessage() == "掉线了"){
                    $this->login();
                }
                if($i == self::MAX_TRYIES) throw new Exception($e);
                sleep(5);
            }
        }
        return $this;
    }

    /**
     * 初步处理数据
     * @return void
     */
    public function handleData(): void
    {
        try{
            $this->contents = $this->contents["data"];
        }catch(Exception $e){
            var_dump($this->contents);
            throw $e;
        }
    }

    public function contents(){
        return $this->contents;
    }

    /**
     * @throws GuzzleException
     * @throws Exception
     */
    public function post($url, $postData): static
    {

        $postData = $this->getQueryData($postData);
        //$postData = '{"group":"HSF","@class":"com.alsc.saas.gw.client.HsfReq","service":"com.alsc.saas.data.reportcenter.sdk.client.gw.frontend.order.businessincome.v2.BusinessIncomeStatisticalV3Client","method":"listByPage","version":"1.0.0","eagleEyeUserData":{},"argTypes":["com.alsc.saas.data.reportcenter.sdk.client.gw.model.businessincome.v3.request.BusinessIncomeV3Req"],"argValues":[{"couponStatisticalType":"BY_NAME","storeStatisticalType":"SEPARATE","orgStatisticsType":"BY_SHOP","shopIds":["40282015"],"dateRange":{"dateType":"FINISH_BUSI_DATE","startDate":1755273600000,"endDate":1755359999999},"periodType":"BY_DAY","orderSourceList":[],"orderTypeList":[],"pageBean":{"pageNum":1,"pageSize":10,"collators":[{"field":"busiDate","desc":true}]},"extInfos":{"pageUri":"/lowcode/business-income","startDate":1755273600000,"endDate":1755359999999}}],"targetClusterName":"alibaba-prod","timeout":"PT30S","context":{"visitedDevice":"WEB"}}';
        $headers = $this->headers();
//        var_dump($headers);
//        exit();
        $response = $this->postData($url,$postData,$headers);
        $this->contents = $this->isLogout($response);
        $this->handleData();
        return $this;
    }

    /**
     * @throws GuzzleException
     * @throws Exception
     */
    public function get($url, $postData): static
    {
        $headers = $this->headers();
//        var_dump($headers);
//        exit();
        $response = $this->getData($url,$postData,$headers);
        $this->contents = $this->isLogout($response);
        $this->handleData();
        return $this;
    }
}
